package com.starry.core.base

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.NonNull
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.starry.core.viewmodel.BaseViewModel
import java.lang.reflect.ParameterizedType

abstract class BaseFragment<VB : ViewDataBinding, VM : BaseViewModel> :
    Fragment() {

    private var isFirstShow = true

    protected lateinit var mContext: AppCompatActivity

    protected lateinit var mDataBinding: VB


    protected val mViewModel: VM by lazy {
        val type = javaClass.genericSuperclass as ParameterizedType
        val aClass = type.actualTypeArguments[1] as Class<VM>
        aClass.getDeclaredConstructor().isAccessible = true
        if (viewModelSyn()) {
            ViewModelProvider(requireActivity()).get(aClass)
        } else {
            ViewModelProvider(this).get(aClass)
        }
    }

    /**
     * viewModel是否使用当前fragment所依赖的activity创建 可以viewModel数据共享
     */
    protected open fun viewModelSyn(): Boolean = false

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is AppCompatActivity) {
            this.mContext = context
        }
    }

    override fun onCreateView(
        @NonNull inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        super.onCreateView(inflater, container, savedInstanceState)
        val type = javaClass.genericSuperclass as ParameterizedType
        val aClass = type.actualTypeArguments[0] as Class<*>
        val method = aClass.getDeclaredMethod(
            "inflate",
            LayoutInflater::class.java,
            ViewGroup::class.java,
            Boolean::class.java
        )
        //反射初始化dataBinding
        method.isAccessible = true//关掉安全检查
        mDataBinding = method.invoke(null, layoutInflater, container, false) as VB
        mDataBinding.lifecycleOwner = this

        return mDataBinding.root
    }

    override fun onResume() {
        super.onResume()
        //是第一次展示，加载数据
        if (isFirstShow) {
            isFirstShow = false
            initView()
            initData()
            createObserver()
        }
    }

    abstract fun createObserver()

    abstract fun initData()

    abstract fun initView()


    override fun onDestroyView() {
        super.onDestroyView()
        mDataBinding.unbind()
        isFirstShow = true
    }

}